package com.eduagent.xwqeduagent.app.agent;

import com.eduagent.xwqeduagent.constant.FileConstant;
import com.eduagent.xwqeduagent.model.vo.LectureAnalysisResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.io.File;
import java.io.IOException;

@Slf4j
@Component
public class LectureAnalysis {

    /**
     * 分析讲义
     * @param content 讲义内容或文件内容
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @param file 上传的文件
     * @return 讲义分析结果
     */
    public LectureAnalysisResultVO lectureAnalysis(String content, String userId, String sessionId, MultipartFile file) {
        log.info("开始讲义分析，内容：{}，用户ID：{}，文件名：{}", 
                content != null ? (content.length() > 100 ? content.substring(0, 100) + "..." : content) : "无内容", 
                userId, 
                file != null ? file.getOriginalFilename() : "无文件");

        // 验证参数
        if ((content == null || content.trim().isEmpty()) && (file == null || file.isEmpty())) {
            return LectureAnalysisResultVO.builder()
                    .status("erroe")
                    .message("讲义内容和文件不能同时为空")
                    .build();
        }

        // Coze API配置
        String cozeApiUrl = "https://api.coze.cn/v3/chat";
        String botId = "7509111109086478376"; // 请替换为实际的botId
        String apiKey = "pat_qm2xo8JAVOw7DGJcgmbpMTENCEst9IBcMt2xxRKig1RJLH9QBHDeEq6jgb2rKCxj"; // 请替换为实际的API密钥

        try {
            // 构建请求体
            cn.hutool.json.JSONObject requestBody = new cn.hutool.json.JSONObject();
            requestBody.set("bot_id", botId);
            requestBody.set("user_id", userId);
            requestBody.set("stream", false);
            requestBody.set("auto_save_history", true);

            // 如果有上传文件，先上传到Coze获取fileId
            String fileId = null;
            if (file != null && !file.isEmpty()) {
                try {
                    // 保存上传的文件到临时目录
                    String uploadDir = FileConstant.FILE_SAVE_DIR + "/lecture_uploads/";
                    cn.hutool.core.io.FileUtil.mkdir(uploadDir);
                    String tempFilePath = uploadDir + sessionId + "_" + file.getOriginalFilename();
                    File tempFile = new File(tempFilePath);
                    file.transferTo(tempFile);
                    
                    // 上传到Coze API获取fileId
                    fileId = uploadFileToCaze(tempFile, apiKey);
                    log.info("文件上传到Coze成功，fileId: {}", fileId);
                } catch (Exception e) {
                    log.error("处理上传文件失败", e);
                    return LectureAnalysisResultVO.builder()
                            .status("erroe")
                            .message("文件上传到Coze失败：" + e.getMessage())
                            .build();
                }
            }

            // 构建消息内容
            cn.hutool.json.JSONArray additionalMessages = new cn.hutool.json.JSONArray();
            cn.hutool.json.JSONObject message = new cn.hutool.json.JSONObject();
            message.set("role", "user");
            
            // 如果有上传文件，使用对象格式
            if (fileId != null) {
                // 构建包含文件的消息内容
                cn.hutool.json.JSONArray objectContent = new cn.hutool.json.JSONArray();
                
                // 添加文件对象
                cn.hutool.json.JSONObject fileObj = new cn.hutool.json.JSONObject();
                fileObj.set("type", getFileTypeForCoze(file.getOriginalFilename()));
                fileObj.set("file_id", fileId);
                objectContent.add(fileObj);
                
                // 添加文本对象
                cn.hutool.json.JSONObject textObj = new cn.hutool.json.JSONObject();
                textObj.set("type", "text");
                textObj.set("text", "请分析以下讲义内容，提供关键点总结：" + (content != null ? content : ""));
                objectContent.add(textObj);
                
                message.set("content", objectContent.toString());
                message.set("content_type", "object_string");
            } else {
                // 无文件，使用普通文本格式
                message.set("content", "请分析以下讲义内容，提供关键点总结：" + content);
                message.set("content_type", "text");
            }
            
            additionalMessages.add(message);
            requestBody.set("additional_messages", additionalMessages);

            // 设置请求头
            HashMap<String, String> headers = new HashMap<>();
            headers.put("Authorization", "Bearer " + apiKey);
            headers.put("Content-Type", "application/json");

            // 发送HTTP请求
            String result = cn.hutool.http.HttpUtil.createPost(cozeApiUrl)
                    .headerMap(headers, true)
                    .body(requestBody.toString())
                    .execute()
                    .body();

            log.info("讲义分析结果：{}", result);

            // 解析响应
            cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

            // 检查状态
            if (responseJson.containsKey("data") && responseJson.getJSONObject("data").containsKey("status")) {
                String status = responseJson.getJSONObject("data").getStr("status");
                String conversationId = responseJson.getJSONObject("data").getStr("conversation_id");
                String chatId = responseJson.getJSONObject("data").getStr("id");

                if ("in_progress".equals(status)) {
                    // 如果状态是"in_progress"，需要轮询获取结果
                    return pollForLectureAnalysisResult(conversationId, botId, apiKey, chatId);
                } else if ("completed".equals(status)) {
                    // 如果已完成，直接处理结果
                    return processLectureAnalysisResult(responseJson, sessionId);
                } else {
                    // 其他状态处理
                    log.warn("讲义分析状态未知：{}", status);
                    return LectureAnalysisResultVO.builder()
                            .status("erroe")
                            .message("讲义分析状态未知"+status)
                            .build();
                }
            } else {
                // 保存原始响应
                String lectureAnalysisPath = FileConstant.FILE_SAVE_DIR + "/lecture_analysis/" + sessionId + "_analysis_raw.json";
                cn.hutool.core.io.FileUtil.writeString(result, lectureAnalysisPath, "UTF-8");

                return LectureAnalysisResultVO.builder()
                        .status("erroe")
                        .message("讲义分析请求已提交，但响应格式不符合预期，已保存原始响应到：" + lectureAnalysisPath)
                        .build();
            }
        } catch (Exception e) {
            log.error("讲义分析失败", e);

            return LectureAnalysisResultVO.builder()
                    .status("erroe")
                    .message("讲义分析失败：" + e.getMessage())
                    .build();
        }
    }
    
    /**
     * 上传文件到Coze API
     * @param file 要上传的文件
     * @param apiKey API密钥
     * @return 文件ID
     */
    private String uploadFileToCaze(File file, String apiKey) throws IOException {
        String uploadUrl = "https://api.coze.cn/v1/files/upload";
        
        // 使用Hutool的HttpUtil上传文件
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("file", file);
        
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        
        String result = cn.hutool.http.HttpUtil.createPost(uploadUrl)
                .headerMap(headers, true)
                .form(paramMap)
                .execute()
                .body();
        
        // 解析响应获取文件ID
        cn.hutool.json.JSONObject jsonResult = new cn.hutool.json.JSONObject(result);
        if (jsonResult.getInt("code") == 0 && jsonResult.containsKey("data")) {
            return jsonResult.getJSONObject("data").getStr("id");
        } else {
            throw new IOException("上传文件到Coze失败: " + jsonResult.getStr("msg"));
        }
    }
    
    /**
     * 根据文件名确定Coze API的文件类型
     * @param fileName 文件名
     * @return 文件类型
     */
    private String getFileTypeForCoze(String fileName) {
        if (fileName == null) {
            return "file";
        }
        
        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        
        // 文档类型
        if (extension.equals("doc") || extension.equals("docx") || 
            extension.equals("xls") || extension.equals("xlsx") || 
            extension.equals("ppt") || extension.equals("pptx") || 
            extension.equals("pdf") || extension.equals("csv")) {
            return "file";
        }
        
        // 图片类型
        if (extension.equals("jpg") || extension.equals("jpeg") || 
            extension.equals("png") || extension.equals("gif") || 
            extension.equals("webp") || extension.equals("bmp")) {
            return "image";
        }
        
        // 音频类型
        if (extension.equals("mp3") || extension.equals("wav") || 
            extension.equals("m4a") || extension.equals("flac")) {
            return "audio";
        }
        
        // 视频类型
        if (extension.equals("mp4") || extension.equals("avi") || 
            extension.equals("mov") || extension.equals("mkv")) {
            return "video";
        }
        
        // 默认为普通文件
        return "file";
    }

    /**
     * 轮询获取讲义分析结果
     */
    private LectureAnalysisResultVO pollForLectureAnalysisResult(String conversationId, String botId, String apiKey, String sessionId) {
        // 构造API地址
        String checkStatusUrl = "https://api.coze.cn/v3/chat/message/list?" +
                "chat_id=" + sessionId +
                "&conversation_id=" + conversationId;

        // 请求头配置
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        headers.put("Content-Type", "application/json");

        // 最多尝试20次，每次间隔3秒
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(3000);
                String result = cn.hutool.http.HttpUtil.createGet(checkStatusUrl)
                        .headerMap(headers, true)
                        .execute()
                        .body();

                log.info("轮询讲义分析状态，第{}次尝试，结果: {}", (i+1), result);
                cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

                // 检查响应状态码
                if (responseJson.getInt("code") == 0) {
                    // 检查是否有data字段且为数组
                    if (responseJson.containsKey("data") && responseJson.get("data") instanceof cn.hutool.json.JSONArray) {
                        // 获取消息列表
                        cn.hutool.json.JSONArray messages = responseJson.getJSONArray("data");
                        if (messages.isEmpty()) {
                            log.info("轮询结果中消息列表为空，继续等待...");
                            continue;
                        }

                        // 遍历消息找到tool_response类型的消息
                        for (int j = 0; j < messages.size(); j++) {
                            cn.hutool.json.JSONObject message = messages.getJSONObject(j);
                            String type = message.getStr("type");
                            if ("tool_response".equals(type)) {
                                // 提取讲义分析内容
                                String content = message.getStr("content");
                                if (content != null && !content.isEmpty()) {
                                    // 处理讲义分析结果
                                    return processLectureAnalysisResult(message, sessionId);
                                }
                            }
                        }
                        log.info("未找到讲义分析结果消息，继续等待...");
                    } else {
                        // 如果没有data数组，可能是因为分析仍在进行中
                        if (responseJson.containsKey("msg") && !responseJson.getStr("msg").isEmpty()) {
                            log.info("讲义分析中，继续等待: {}", responseJson.getStr("msg"));
                        } else {
                            log.info("讲义分析中，继续等待...");
                        }
                    }
                } else {
                    // 非零状态码，表示有错误
                    String errorMsg = responseJson.getStr("msg");
                    log.warn("轮询讲义分析遇到错误，状态码: {}, 错误信息: {}", responseJson.getInt("code"), errorMsg);
                    
                    if (i >= 10) {  // 如果已经尝试了超过10次，返回错误
                        return LectureAnalysisResultVO.builder()
                                .status("error")
                                .message("讲义分析遇到错误: " + errorMsg)
                                .build();
                    }
                }
            } catch (Exception e) {
                log.error("轮询讲义分析状态出现异常", e);
            }
        }

        // 所有尝试失败后，直接获取最终结果尝试一次
        try {
            String chatUrl = "https://api.coze.cn/v3/chat/message?id=" + sessionId;
            String finalResult = cn.hutool.http.HttpUtil.createGet(chatUrl)
                    .headerMap(headers, true)
                    .execute()
                    .body();
            
            log.info("尝试获取最终分析结果: {}", finalResult);
            cn.hutool.json.JSONObject finalJson = new cn.hutool.json.JSONObject(finalResult);
            
            if (finalJson.getInt("code") == 0 && finalJson.containsKey("data")) {
                cn.hutool.json.JSONObject data = finalJson.getJSONObject("data");
                if (data.containsKey("content")) {
                    String content = data.getStr("content");
                    if (content != null && !content.isEmpty()) {
                        return LectureAnalysisResultVO.builder()
                                .status("success")
                                .analysisContent(content)
                                .message(content)
                                .build();
                    }
                }
            }
        } catch (Exception e) {
            log.error("获取最终结果失败", e);
        }

        return LectureAnalysisResultVO.builder()
                .status("error")
                .message("讲义分析超时，请稍后再试")
                .build();
    }

    /**
     * 处理讲义分析结果
     * @param sessionId 会话ID（用于文件命名）
     * @return 结果信息（包含结果内容或错误信息）
     */
    private LectureAnalysisResultVO processLectureAnalysisResult(cn.hutool.json.JSONObject messageJson, String sessionId) {
        try {
            // 从消息中提取content字段
            String content = messageJson.getStr("content");
            if (cn.hutool.core.util.StrUtil.isBlank(content)) {
                throw new IllegalArgumentException("消息中缺少content字段");
            }

            log.info("原始讲义分析内容，长度: {}", content.length());
            
            // 提取纯文本内容（去除Markdown和HTML格式）
            String purifiedContent = extractPurifiedText(content);
            log.info("提取后的纯文本内容，长度: {}", purifiedContent.length());

            // 直接返回结果，不保存到文件
            return LectureAnalysisResultVO.builder()
                    .status("success")
                    .message("成功")
                    .analysisContent(purifiedContent)
                    .build();
        } catch (Exception e) {
            // 异常处理
            String errorMessage = "处理讲义分析结果失败";
            if (e instanceof IllegalArgumentException) {
                log.warn("{}：{}", errorMessage, e.getMessage());
                return LectureAnalysisResultVO.builder()
                        .status("error")
                        .message(errorMessage)
                        .build();
            } else {
                log.error(errorMessage, e);
                return LectureAnalysisResultVO.builder()
                        .status("error")
                        .message(errorMessage + "：" + e.getClass().getSimpleName())
                        .build();
            }
        }
    }
    
    /**
     * 提取纯文本内容，去除Markdown和HTML标记
     * @param content 原始内容
     * @return 提取后的纯文本
     */
    private String extractPurifiedText(String content) {
        if (content == null) {
            return "";
        }
        
        String result = content;
        
        // 移除HTML标签
        result = result.replaceAll("<[^>]+>", "");
        
        // 移除Markdown标题标记
        result = result.replaceAll("#{1,6} ", "");
        
        // 移除Markdown链接，保留链接文本
        result = result.replaceAll("!?\\[(.*?)\\]\\(.*?\\)", "$1");
        
        // 移除Markdown强调标记（*和_）
        result = result.replaceAll("([*_]{1,3})(.*?)\\1", "$2");
        
        // 移除代码块标记
        result = result.replaceAll("```[\\s\\S]*?```", ""); // 多行代码块
        result = result.replaceAll("`([^`]*)`", "$1"); // 行内代码
        
        // 移除引用符号
        result = result.replaceAll("^\\s*>\\s*", ""); 
        
        // 移除分隔线
        result = result.replaceAll("^-{3,}$", "");
        result = result.replaceAll("^\\*{3,}$", "");
        
        // 移除多余的空行
        result = result.replaceAll("(\\n\\s*){3,}", "\n\n");
        
        // 修剪空白
        result = result.trim();
        
        return result;
    }
}
